-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bugfix] Fix broken bytecode dependency #14929
Conversation
⏱️ 1h 19m total CI duration on this PR
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #14929 +/- ##
=======================================
Coverage 60.1% 60.1%
=======================================
Files 856 856
Lines 210845 210905 +60
=======================================
+ Hits 126742 126788 +46
- Misses 84103 84117 +14 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I played with it and can confirm that it has fixed the create-object-and-publish-package
workflow.
Left some comments on the implementation.
BTW I also discovered that aptos move unit-test
would fail if you run it within a package with a bytecode dependency, so we should get that fixed as well. No need to include it in this PR though
let (file_map, all_compiled_units, optional_global_env) = | ||
match config.compiler_version.unwrap_or_default() { | ||
CompilerVersion::V1 => { | ||
let mut paths = src_deps; | ||
paths.push(sources_package_paths.clone()); | ||
let compiler = Compiler::from_package_paths( | ||
paths, | ||
bytecode_deps.clone(), | ||
flags, | ||
&known_attributes, | ||
); | ||
compiler_driver_v1(compiler)? | ||
}, | ||
version @ CompilerVersion::V2_0 | version @ CompilerVersion::V2_1 => { | ||
let to_str_vec = |ps: &[Symbol]| { | ||
ps.iter() | ||
.map(move |s| s.as_str().to_owned()) | ||
.collect::<Vec<_>>() | ||
}; | ||
let mut global_address_map = BTreeMap::new(); | ||
for pack in std::iter::once(&sources_package_paths) | ||
.chain(src_deps.iter()) | ||
.chain(bytecode_deps.iter()) | ||
{ | ||
for (name, val) in &pack.named_address_map { | ||
if let Some(old) = | ||
global_address_map.insert(name.as_str().to_owned(), *val) | ||
{ | ||
if old != *val { | ||
let pack_name = pack | ||
.name | ||
.map(|s| s.as_str().to_owned()) | ||
.unwrap_or_else(|| "<unnamed>".to_owned()); | ||
bail!( | ||
"found remapped address alias `{}` (`{} != {}`) in package `{}`\ | ||
, please use unique address aliases across dependencies", | ||
name, old, val, pack_name | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
let mut options = move_compiler_v2::Options { | ||
sources: sources_package_paths | ||
.paths | ||
.iter() | ||
.map(|path| path.as_str().to_owned()) | ||
.collect(), | ||
sources_deps: src_deps.iter().flat_map(|x| to_str_vec(&x.paths)).collect(), | ||
dependencies: bytecode_deps | ||
.iter() | ||
.flat_map(|x| to_str_vec(&x.paths)) | ||
.collect(), | ||
named_address_mapping: global_address_map | ||
.into_iter() | ||
.map(|(k, v)| format!("{}={}", k, v)) | ||
.collect(), | ||
skip_attribute_checks, | ||
known_attributes: known_attributes.clone(), | ||
language_version: Some(effective_language_version), | ||
compiler_version: Some(version), | ||
compile_test_code: flags.keep_testing_functions(), | ||
experiments: config.experiments.clone(), | ||
..Default::default() | ||
}; | ||
options = options.set_experiment(Experiment::ATTACH_COMPILED_MODULE, true); | ||
compiler_driver_v2(options)? | ||
}, | ||
}; | ||
let mut options = move_compiler_v2::Options { | ||
sources: sources_package_paths | ||
.paths | ||
.iter() | ||
.map(|path| path.as_str().to_owned()) | ||
.collect(), | ||
sources_deps: src_deps.iter().flat_map(|x| to_str_vec(&x.paths)).collect(), | ||
dependencies: bytecode_deps | ||
.iter() | ||
.flat_map(|x| to_str_vec(&x.paths)) | ||
.collect(), | ||
named_address_mapping: global_address_map | ||
.into_iter() | ||
.map(|(k, v)| format!("{}={}", k, v)) | ||
.collect(), | ||
skip_attribute_checks, | ||
known_attributes: known_attributes.clone(), | ||
language_version: Some(effective_language_version), | ||
compiler_version: Some(version), | ||
compile_test_code: flags.keep_testing_functions(), | ||
experiments: config.experiments.clone(), | ||
..Default::default() | ||
}; | ||
options = options.set_experiment(Experiment::ATTACH_COMPILED_MODULE, true); | ||
compiler_driver_v2(options)? | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fEst1ck it seems like these are just formatting changes. Can you confirm if this is indeed the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
let mut bytecode_deps = vec![]; | ||
for dep_name in self.package.bytecode_deps.iter().copied() { | ||
let bytecode_paths = self.get_compiled_units_paths(dep_name)?; | ||
let mut addrs = BTreeSet::new(); | ||
for bytecode_path in bytecode_paths { | ||
let addr = get_module_addr(dep_name, bytecode_path.as_str())?; | ||
addrs.insert(addr); | ||
} | ||
for addr in addrs { | ||
bytecode_deps.push((dep_name, addr)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not so sure if the logic here is correct.
get_compiled_units_paths
doesn't seem to have the ability to locate a bytecode dependency just by its name (without the address)- Similar to my other comment, there is no handling of duplicates
With that being said this function only seems to be referenced by some move-cli
tests and it does not seem to be reachable from there either due to track_cov
being set to false. Not sure if there's a good way to even test this.
fn run_all(args_path: &Path) -> datatest_stable::Result<()> {
let cli_exe = env!("CARGO_BIN_EXE_move");
let use_temp_dir = !args_path.parent().unwrap().join("NO_TEMPDIR").exists();
run_one(
args_path,
&PathBuf::from(cli_exe),
/* use_temp_dir */ use_temp_dir,
/* track_cov */ false,
)?;
Ok(())
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed this part and left a TODO
@@ -1138,3 +1173,23 @@ pub fn build_and_report_no_exit_v2_driver( | |||
Some(env), | |||
)) | |||
} | |||
|
|||
/// Returns the address of the module | |||
fn get_module_addr(pkg_name: Symbol, pkg_path: &str) -> Result<NumericalAddress> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if module_path
would be a less confusing name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn get_package_module_addr
or maybe fn get_addr_from_module_in_package
might be a bit explicit with what this function does as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
bytecode_deps: bytecode_deps | ||
.iter() | ||
.flat_map(|package| { | ||
let name = package.name.unwrap(); | ||
package.paths.iter().map(move |pkg_path| { | ||
get_module_addr(name, pkg_path.as_str()).map(|addr| (name, addr)) | ||
}) | ||
}) | ||
.try_collect()?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get that you're trying to get the address of a compiled package, but the implementation seems a bit awkward
pkg_path
technically already contains the address of the package (e.g."/home/vgao/aptos-core/b/deps/0x8ae94b63db9b31761835258cd938ef670235069d37c17c616d06d28860dffe87/A/build/bytecode_modules/a.mv"
), so you don't have to deserialize a module and then get the address from there.- The current code does not seem to handle bytecode packages with multiple modules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The package path part in the file structure
0x8ae94b63db9b31761835258cd938ef670235069d37c17c616d06d28860dffe87/A/build/bytecode_modules/a.mv
is not required in the Move book. - changed field to
pub bytecode_deps: BTreeMap<PackageName, NumericalAddress>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to have a better explanation of what is actually fixed. Also, it might be hard, but there is no test case? In this case pl justify why not.
@@ -153,6 +156,18 @@ impl OnDiskCompiledPackage { | |||
deps_compiled_units.push((dep_name, self.decode_unit(dep_name, &bytecode_path)?)) | |||
} | |||
} | |||
let mut bytecode_deps = vec![]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused here -- isn't into_compiled_package only used by collect_coverage in the Move CLI? But the bug seems to be about deployment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is irrelevant to this fix. Removed.
Since testing this requires publishing a package with bytecode dependencies which is hard to be done automatically, we tested this maually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM for now. Can you add a comment at the location where you deleted the following code as well, just for more clarity?
let mut bytecode_deps = vec![];
for dep_name in self.package.bytecode_deps.iter().copied() {
let bytecode_paths = self.get_compiled_units_paths(dep_name)?;
let mut addrs = BTreeSet::new();
for bytecode_path in bytecode_paths {
let addr = get_module_addr(dep_name, bytecode_path.as_str())?;
addrs.insert(addr);
}
for addr in addrs {
bytecode_deps.push((dep_name, addr));
}
}
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
✅ Forge suite
|
✅ Forge suite
|
✅ Forge suite
|
Description
Fixed #14311. This PR continues the partial fix from @jasonxh #14340 by
OnDiskPackage
The original issue is caused by
CompiledPackage
missing information for bytecode dependencies, which propagates toPackageMetadata
when constructing transaction payloads.How Has This Been Tested?
This is manually tested on the #14311
Type of Change
Which Components or Systems Does This Change Impact?